package demoMod.anm2editor.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.math.Interpolation;
import demoMod.anm2editor.fonts.FontKeys;
import demoMod.anm2editor.interfaces.ReloadStringsSubscriber;
import demoMod.anm2editor.localization.LocalizedStrings;
import demoMod.anm2editor.model.KeyFrame;
import demoMod.anm2editor.model.Operation;
import demoMod.anm2editor.model.Project;
import demoMod.anm2editor.model.Track;
import demoMod.gdxform.core.FormManager;
import demoMod.gdxform.enums.GFrameCloseStrategy;
import demoMod.gdxform.enums.GFrameWindowMode;
import demoMod.gdxform.enums.GFrameWindowStyle;
import demoMod.gdxform.helpers.FontHelper;
import demoMod.gdxform.ui.GButton;
import demoMod.gdxform.ui.GFrame;
import demoMod.gdxform.ui.GLabel;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

public class BakeWindow extends GFrame implements ReloadStringsSubscriber {
    private final HistoryPanel historyPanel;
    private final KeyFrame frameToBake;
    private final Track track;
    private KeyFrame nextFrame;
    private final List<KeyFrame> bakedFrames = new ArrayList<>();
    private boolean confirmed = false;

    private final Supplier<Interpolation> defaultCurveProvider = () -> new Interpolation() {
        @Override
        public float apply(float a) {
            return 0;
        }
    };

    private Interpolation xPosCurve = defaultCurveProvider.get();
    private Interpolation yPosCurve = defaultCurveProvider.get();
    private Interpolation xOriginCurve = defaultCurveProvider.get();
    private Interpolation yOriginCurve = defaultCurveProvider.get();
    private Interpolation xSrcCurve = defaultCurveProvider.get();
    private Interpolation ySrcCurve = defaultCurveProvider.get();
    private Interpolation srcWidthCurve = defaultCurveProvider.get();
    private Interpolation srcHeightCurve = defaultCurveProvider.get();
    private Interpolation xScaleCurve = defaultCurveProvider.get();
    private Interpolation yScaleCurve = defaultCurveProvider.get();
    private Interpolation rotationCurve = defaultCurveProvider.get();
    private Interpolation visibleCurve = defaultCurveProvider.get();
    private Interpolation tintRCurve = defaultCurveProvider.get();
    private Interpolation tintGCurve = defaultCurveProvider.get();
    private Interpolation tintBCurve = defaultCurveProvider.get();
    private Interpolation tintACurve = defaultCurveProvider.get();
    private Interpolation colorOffsetRCurve = defaultCurveProvider.get();
    private Interpolation colorOffsetGCurve = defaultCurveProvider.get();
    private Interpolation colorOffsetBCurve = defaultCurveProvider.get();

    public BakeWindow(BitmapFont bannerFont, KeyFrame frameToBake) {
        super(Gdx.graphics.getWidth() / 2.0F - Gdx.graphics.getWidth() * 0.075F, Gdx.graphics.getHeight() / 2.0F - Gdx.graphics.getHeight() * 0.3F, Gdx.graphics.getWidth() * 0.15F, Gdx.graphics.getHeight() * 0.6F - 45, FontHelper.getFont(FontKeys.SIM_HEI_14), GFrameWindowStyle.CLOSE_BUTTON_ONLY, false);
        setWindowMode(GFrameWindowMode.MODAL);
        this.frameToBake = frameToBake;
        Timeline timeline = ((Timeline)FormManager.getInstance().getContainerById(Timeline.ID));
        track = timeline.getCurrentSelectedTrack();
        List<KeyFrame> keyFrames = track.getContent(Project.currentProject.getCurrentAnimation().getName()).getKeyFrames();
        List<KeyFrame> originalKeyFrames = new ArrayList<>(keyFrames);
        for (KeyFrame keyFrame : keyFrames) {
            if (keyFrame == frameToBake) {
                int index = keyFrames.indexOf(keyFrame);
                if (keyFrames.size() - 1 == index) {
                    nextFrame = frameToBake.makeCopy();
                } else {
                    nextFrame = keyFrames.get(index + 1);
                }
                break;
            }
        }

        for (int i=0;i<frameToBake.delay;i++) {
            KeyFrame frame = frameToBake.makeCopy();
            frame.delay = 1;
            frame.interpolated = true;
            bakedFrames.add(frame);
        }

        int index = keyFrames.indexOf(frameToBake);
        keyFrames.remove(frameToBake);
        keyFrames.addAll(index, bakedFrames);

        List<String> strings = LocalizedStrings.getStrings("BakeWindow");
        setTitle(strings.get(0));
        setResizable(false);
        setCloseStrategy(GFrameCloseStrategy.EXIT_ON_CLOSE);
        LocalizedStrings.subscribe(this);
        historyPanel = (HistoryPanel) FormManager.getInstance().getContainerById(HistoryPanel.ID);
        GLabel lPosition = new GLabel(getWidth() * 0.05F, getHeight() * 0.88F + getHeight() * 0.035F, getWidth(), getHeight() * 0.07F, bannerFont);
        lPosition.setText(strings.get(1));
        lPosition.setId("lPosition");
        GLabel lOrigin = new GLabel(getWidth() * 0.05F, getHeight() * 0.8F + getHeight() * 0.035F, getWidth(), getHeight() * 0.07F, bannerFont);
        lOrigin.setText(strings.get(2));
        lOrigin.setId("lOrigin");
        GLabel lSrc = new GLabel(getWidth() * 0.05F, getHeight() * 0.72F + getHeight() * 0.035F, getWidth(), getHeight() * 0.07F, bannerFont);
        lSrc.setText(strings.get(3));
        lSrc.setId("lSrc");
        GLabel lSize = new GLabel(getWidth() * 0.05F, getHeight() * 0.64F + getHeight() * 0.035F, getWidth(), getHeight() * 0.07F, bannerFont);
        lSize.setText(strings.get(4));
        lSize.setId("lSize");
        GLabel lScale = new GLabel(getWidth() * 0.05F, getHeight() * 0.56F + getHeight() * 0.035F, getWidth(), getHeight() * 0.07F, bannerFont);
        lScale.setText(strings.get(5));
        lScale.setId("lScale");
        GLabel lRotation = new GLabel(getWidth() * 0.05F, getHeight() * 0.48F + getHeight() * 0.035F, getWidth(), getHeight() * 0.07F, bannerFont);
        lRotation.setText(strings.get(7));
        lRotation.setId("lRotation");
        GLabel lVisible = new GLabel(getWidth() * 0.05F, getHeight() * 0.4F + getHeight() * 0.035F, getWidth(), getHeight() * 0.07F, bannerFont);
        lVisible.setText(strings.get(8));
        lVisible.setId("lVisible");
        GLabel lTint = new GLabel(getWidth() * 0.05F, getHeight() * 0.32F + getHeight() * 0.035F, getWidth(), getHeight() * 0.07F, bannerFont);
        lTint.setText(strings.get(9));
        lTint.setId("lTint");
        GLabel lColorOffset = new GLabel(getWidth() * 0.05F, getHeight() * 0.24F + getHeight() * 0.035F, getWidth(), getHeight() * 0.07F, bannerFont);
        lColorOffset.setText(strings.get(10));
        lColorOffset.setId("lColorOffset");

        addElement(lPosition);
        addElement(lOrigin);
        addElement(lSrc);
        addElement(lSize);
        addElement(lScale);
        addElement(lRotation);
        addElement(lVisible);
        addElement(lTint);
        addElement(lColorOffset);

        GButton x = new GButton(getWidth() * 0.35F, lPosition.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, xPosCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.xPosition = interpolation.apply(frameToBake.xPosition, nextFrame.xPosition, progress);
                    }
                    xPosCurve = interpolation;
                });
            }
        };
        x.setFgTexture(new Texture("buttons/reset_activated.png"));
        x.setId("x");
        x.setText("");

        GButton y = new GButton(getWidth() * 0.55F + 3, lPosition.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, yPosCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.yPosition = interpolation.apply(frameToBake.yPosition, nextFrame.yPosition, progress);
                    }
                    yPosCurve = interpolation;
                });
            }
        };
        y.setFgTexture(new Texture("buttons/reset_activated.png"));
        y.setId("y");
        y.setText("");

        GButton xOrigin = new GButton(getWidth() * 0.35F, lOrigin.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, xOriginCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.xPivot = interpolation.apply(frameToBake.xPivot, nextFrame.xPivot, progress);
                    }
                    xOriginCurve = interpolation;
                });
            }
        };
        xOrigin.setFgTexture(new Texture("buttons/reset_activated.png"));
        xOrigin.setId("xOrigin");
        xOrigin.setText("");

        GButton yOrigin = new GButton(getWidth() * 0.55F + 3, lOrigin.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, yOriginCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.yPivot = interpolation.apply(frameToBake.yPivot, nextFrame.yPivot, progress);
                    }
                    yOriginCurve = interpolation;
                });
            }
        };
        yOrigin.setFgTexture(new Texture("buttons/reset_activated.png"));
        yOrigin.setId("yOrigin");
        yOrigin.setText("");

        GButton xSrc = new GButton(getWidth() * 0.35F, lSrc.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, xSrcCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.xCrop = (int) interpolation.apply(frameToBake.xCrop, nextFrame.xCrop, progress);
                    }
                    xSrcCurve = interpolation;
                });
            }
        };
        xSrc.setFgTexture(new Texture("buttons/reset_activated.png"));
        xSrc.setId("xSrc");
        xSrc.setText("");

        GButton ySrc = new GButton(getWidth() * 0.55F + 3, lSrc.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, ySrcCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.yCrop = (int) interpolation.apply(frameToBake.yCrop, nextFrame.yCrop, progress);
                    }
                    ySrcCurve = interpolation;
                });
            }
        };
        ySrc.setFgTexture(new Texture("buttons/reset_activated.png"));
        ySrc.setId("ySrc");
        ySrc.setText("");

        GButton width = new GButton(getWidth() * 0.35F, lSize.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, srcWidthCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.width = (int) interpolation.apply(frameToBake.width, nextFrame.width, progress);
                    }
                    srcWidthCurve = interpolation;
                });
            }
        };
        width.setFgTexture(new Texture("buttons/reset_activated.png"));
        width.setId("width");
        width.setText("");

        GButton height = new GButton(getWidth() * 0.55F + 3, lSize.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, srcHeightCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.height = (int) interpolation.apply(frameToBake.height, nextFrame.height, progress);
                    }
                    srcHeightCurve = interpolation;
                });
            }
        };
        height.setFgTexture(new Texture("buttons/reset_activated.png"));
        height.setId("height");
        height.setText("");

        GButton xScale = new GButton(getWidth() * 0.35F, lScale.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, xScaleCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.xScale = interpolation.apply(frameToBake.xScale, nextFrame.xScale, progress);
                    }
                    xScaleCurve = interpolation;
                });
            }
        };
        xScale.setFgTexture(new Texture("buttons/reset_activated.png"));
        xScale.setId("xScale");
        xScale.setText("");

        GButton yScale = new GButton(getWidth() * 0.55F + 3, lScale.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, yScaleCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.yScale = interpolation.apply(frameToBake.yScale, nextFrame.yScale, progress);
                    }
                    yScaleCurve = interpolation;
                });
            }
        };
        yScale.setFgTexture(new Texture("buttons/reset_activated.png"));
        yScale.setId("yScale");
        yScale.setText("");

        GButton rotation = new GButton(getWidth() * 0.35F, lRotation.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, rotationCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.rotation = interpolation.apply(frameToBake.rotation, nextFrame.rotation, progress);
                    }
                    rotationCurve = interpolation;
                });
            }
        };
        rotation.setFgTexture(new Texture("buttons/reset_activated.png"));
        rotation.setId("rotation");
        rotation.setText("");

        GButton visible = new GButton(getWidth() * 0.35F, lVisible.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, visibleCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.visible = interpolation.apply(frameToBake.visible ? 1 : 0, nextFrame.visible ? 1 : 0, progress) < 0.5F ? keyFrame.visible : nextFrame.visible;
                    }
                    visibleCurve = interpolation;
                });
            }
        };
        visible.setFgTexture(new Texture("buttons/reset_activated.png"));
        visible.setId("visible");
        visible.setText("");

        GButton tintR = new GButton(getWidth() * 0.25F, lTint.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, tintRCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.tint.r = interpolation.apply(frameToBake.tint.r, nextFrame.tint.r, progress);
                    }
                    tintRCurve = interpolation;
                });
            }
        };
        tintR.setFgTexture(new Texture("buttons/reset_activated.png"));
        tintR.setId("tintR");
        tintR.setText("");

        GButton tintG = new GButton(getWidth() * 0.4F + 3, lTint.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, tintGCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.tint.g = interpolation.apply(frameToBake.tint.g, nextFrame.tint.g, progress);
                    }
                    tintGCurve = interpolation;
                });
            }
        };
        tintG.setFgTexture(new Texture("buttons/reset_activated.png"));
        tintG.setId("tintG");
        tintG.setText("");

        GButton tintB = new GButton(getWidth() * 0.55F + 6, lTint.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, tintBCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.tint.b = interpolation.apply(frameToBake.tint.b, nextFrame.tint.b, progress);
                    }
                    tintBCurve = interpolation;
                });
            }
        };
        tintB.setFgTexture(new Texture("buttons/reset_activated.png"));
        tintB.setId("tintB");
        tintB.setText("");

        GButton tintA = new GButton(getWidth() * 0.7F + 9, lTint.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, tintACurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.tint.a = interpolation.apply(frameToBake.tint.a, nextFrame.tint.a, progress);
                    }
                    tintACurve = interpolation;
                });
            }
        };
        tintA.setFgTexture(new Texture("buttons/reset_activated.png"));
        tintA.setId("tintA");
        tintA.setText("");

        GButton offsetR = new GButton(getWidth() * 0.45F, lColorOffset.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, colorOffsetRCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.colorOffset.r = interpolation.apply(frameToBake.colorOffset.r, nextFrame.colorOffset.r, progress);
                    }
                    colorOffsetRCurve = interpolation;
                });
            }
        };
        offsetR.setFgTexture(new Texture("buttons/reset_activated.png"));
        offsetR.setId("offsetR");
        offsetR.setText("");

        GButton offsetG = new GButton(getWidth() * 0.6F + 3, lColorOffset.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, colorOffsetGCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.colorOffset.g = interpolation.apply(frameToBake.colorOffset.g, nextFrame.colorOffset.g, progress);
                    }
                    colorOffsetGCurve = interpolation;
                });
            }
        };
        offsetG.setFgTexture(new Texture("buttons/reset_activated.png"));
        offsetG.setId("offsetG");
        offsetG.setText("");

        GButton offsetB = new GButton(getWidth() * 0.75F + 6, lColorOffset.getY(false) - getHeight() * 0.03F, getWidth() * 0.1F, getWidth() * 0.1F, bannerFont) {
            @Override
            public void onClick() {
                new CurveEditWindow(frameToBake, bakedFrames, originalKeyFrames, colorOffsetBCurve, interpolation -> {
                    for (KeyFrame keyFrame : bakedFrames) {
                        float progress = bakedFrames.indexOf(keyFrame) / (float) bakedFrames.size();
                        keyFrame.colorOffset.b = interpolation.apply(frameToBake.colorOffset.b, nextFrame.colorOffset.b, progress);
                    }
                    colorOffsetBCurve = interpolation;
                });
            }
        };
        offsetB.setFgTexture(new Texture("buttons/reset_activated.png"));
        offsetB.setId("offsetB");
        offsetB.setText("");

        addElement(x);
        addElement(y);
        addElement(xOrigin);
        addElement(yOrigin);
        addElement(xSrc);
        addElement(ySrc);
        addElement(width);
        addElement(height);
        addElement(xScale);
        addElement(yScale);
        addElement(rotation);
        addElement(visible);
        addElement(tintR);
        addElement(tintG);
        addElement(tintB);
        addElement(tintA);
        addElement(offsetR);
        addElement(offsetG);
        addElement(offsetB);

        GButton confirm = new GButton(getWidth() * 0.5F, 10, getWidth() * 0.2F, 20, FontHelper.getFont(FontKeys.SIM_HEI_14)) {
            @Override
            public void onClick() {
                confirmed = true;
                FormManager.getInstance().removeContainer(BakeWindow.this);
            }
        };
        confirm.setText(strings.get(11));
        confirm.setBackground(new Color(0, 47.0F / 255.0F, 147.0F / 255.0F, 1.0F));
        confirm.setBorderWidth(2);
        confirm.setBorder(Color.LIGHT_GRAY.cpy());
        GButton cancel = new GButton(getWidth() * 0.75F, 10, getWidth() * 0.2F, 20, FontHelper.getFont(FontKeys.SIM_HEI_14)) {
            @Override
            public void onClick() {
                FormManager.getInstance().removeContainer(BakeWindow.this);
            }
        };
        cancel.setText(strings.get(12));
        cancel.setBackground(Color.LIGHT_GRAY.cpy());
        cancel.setBorderWidth(2);
        cancel.setBorder(Color.LIGHT_GRAY.cpy());

        addElement(confirm);
        addElement(cancel);

        int totalDelay = 0;
        for (int i=0;i<index;i++) {
            totalDelay += keyFrames.get(i).delay;
        }
        final int startFrameIndex = totalDelay;
        final int endFrameIndex = startFrameIndex + bakedFrames.size();

        GButton preview = new GButton(getWidth() * 0.75F, 35, getWidth() * 0.2F, 20, FontHelper.getFont(FontKeys.SIM_HEI_14)) {
            @Override
            public void onClick() {
                if (timeline.isPlaying()) {
                    timeline.pause();
                    timeline.setPointerIndex(startFrameIndex);
                } else {
                    timeline.play();
                }
            }

            @Override
            public void update() {
                super.update();
                if (timeline.getPointerIndex() > endFrameIndex || timeline.getPointerIndex() < startFrameIndex) {
                    timeline.setPointerIndex(startFrameIndex);
                }
            }
        };
        preview.setText(strings.get(13));
        preview.setBackground(new Color(0, 47.0F / 255.0F, 147.0F / 255.0F, 1.0F));
        preview.setBorderWidth(2);
        preview.setBorder(Color.LIGHT_GRAY.cpy());

        addElement(preview);
    }

    @Override
    public void onReloadStrings() {

    }

    @Override
    public void dispose() {
        super.dispose();
        if (!confirmed) {
            cancelChange();
        } else {
            Operation operation = new Operation() {
                @Override
                public void undo() {
                    cancelChange();
                }

                @Override
                public void redo() {
                    List<KeyFrame> keyFrames = track.getContent(Project.currentProject.getCurrentAnimation().getName()).getKeyFrames();
                    for (KeyFrame keyFrame : keyFrames) {
                        if (keyFrame == frameToBake) {
                            int index = keyFrames.indexOf(keyFrame);
                            if (keyFrames.size() - 1 == index) {
                                nextFrame = frameToBake.makeCopy();
                            } else {
                                nextFrame = keyFrames.get(index + 1);
                            }
                            break;
                        }
                    }

                    int index = keyFrames.indexOf(frameToBake);
                    keyFrames.remove(frameToBake);
                    keyFrames.addAll(index, bakedFrames);
                }
            };
            List<String> strings = LocalizedStrings.getStrings("BakeWindow");
            operation.setName(strings.get(0));
            historyPanel.addOperation(operation);
        }
    }

    private void cancelChange() {
        List<KeyFrame> keyFrames = track.getContent(Project.currentProject.getCurrentAnimation().getName()).getKeyFrames();
        int index = keyFrames.indexOf(bakedFrames.get(0));
        keyFrames.removeAll(bakedFrames);
        keyFrames.add(index, frameToBake);
    }
}
